#ifndef FSXWSMAINWINDOW_H
#define FSXWSMAINWINDOW_H

#include <QMainWindow>
#include <QModelIndex>
#include <QDebug>
#include <QList>
#include <QStandardItemModel>
#include <QTimer>
#include <QMessageBox>
#include <QItemSelection>
#include <QFileDialog>
#include <QInputDialog>
#include <QTableView>
#include <QDesktopServices>
#include <QAction>
#include "fsxwsconfiguredialog.h"
#include "fsxwsabout.h"
#include "fsxwssettings.h"
#include "FsxWsGUI_global.h"
#include "../FsxWebService/requestdispatcher.h"
#include "../FSXSimConnect/fsxsimconnect.h"
#include "../FSXSimConnect/fsxhelper.h"
#include "../FSXSimConnect/aircraft.h"
#include "../FsxWsUtils/mathhelper.h"
#include "../../../QtWebApp/current/lib/bfLogging/src/dualfilelogger.h"
using namespace FsxWebService;

namespace Ui { class FsxWsMainWindow; }
namespace FsxWsGUI {

//! Main application window.
class FsxWsMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    //! Standard constructor.
    /*! \param parent Qt parent widget */
    explicit FsxWsMainWindow(QWidget *parent = 0);
    //! Destructor
    ~FsxWsMainWindow();
    QString Version; /*!< Version number */
private:
    Ui::FsxWsMainWindow* ui; /*!< Main window */
    FsxWsConfigureDialog* _configureDialog;  /*!< Configure (settings) dialog */
    FsxWsAbout* _aboutDialog; /*!< About dialog */
    RequestDispatcher* _webServerDispatcher; /*!< Web server dispatcher */
    FSXSimConnect* _fsxSimConnect; /*!< SimConnect object with the message loop */
    FsxWsSettings* _fsxWsSettings; /*!< Settings for the application */
    QStandardItemModel* _aircraftsViewDataModel; /*!< Data model for the aircrafts */
    QStandardItemModel* _waypointsViewDataModel; /*!< Data model for the waypoints */
    QStandardItemModel* _deltaWaypointsViewDataModel; /*!< Data model for the delta waypoints */
    QTimer* _aircraftUpdateTimer; /*!< Timer used for updating the aircraft's view */
    Logger* _logger; /*!< logger used */
    Aircraft _lastSelectedAircraft; /*!< latest aircraft selected */
    bool _metaDataRegistered; /*!< have the metadata been registerd? */
    //! Main init methods, the specialized init methods will be called from here
    void init();
    //! Init the GUI.
    void initGUI();
    //! Init the settings.
    void initSettings();
    //! Init the logger.
    void initLogger();
    //! Init the FSX signals / metadata.
    void initGUI2FSXSignalsAndMetadata();
    //! Init the Web services buttons (enabled/disabled)
    void initWebServiceButtons();
    //! Init the SimConnect buttons (enabled/disabled)
    void initFsxSimConnectButtons();
    //! Init the aircrafts table view.
    void initAircraftsTableView();
    //! Init the waypoints table view.
    void initWaypointsTableView();
    //! Init the table view.
    /*! \param itemModel corresponding model
        \param tableView view */
    void initWaypointsTableView(QStandardItemModel *itemModel, QTableView *tableView);
    //! Init aircraft update timer.
    void initAircraftUpdateTimer();
    //! Init context meus.
    void initContextMenus();
    //! Testing some prerequisites of the application.
    void startupCheck();
    //! Terminate the application.
    void terminate();
    //! Show a particular configuration dialog tab.
    /*! \param index tab selected */
    void showConfigureTab(int index);
    //! Start the web server.
    bool startWebServer();
    //! Stop the web server.
    bool stopWebServer();
    //! Connect to FSX via SimConnect object and init signal/slots.
    /*! \sa FsxSimConnect */
    bool connectFsxSimConnect();
    //! Disconnect from FSX and disconnect signal / slots
    /*! \param hard do not wait for disconnection */
    bool disconnectFsxSimConnect(bool hard=false);
    //! Connect the web server signal/slots.
    void simConnectWebServerSignalSlot();
    //! Update the aircraft list.
    /*! \param aircrafts */
    void updateAircraftList(const QList<Aircraft>& aircrafts);
    //! Update the waypoints list.
    /*! \param waypoints
        \param deltaWaypoints
        \param title meaningful title */
    void updateWaypointLists(const QList<Waypoint> &waypoints, const QList<Waypoint> &deltaWaypoints, const QString title);
    //! Add single aircraft to aircraft view.
    /*! \param aircraft
        \sa addAircraftsToView */
    void addAircraftToView(const Aircraft& aircraft);
    //! Add aircrafts to aircraft view.
    /*! \param aircrafts
        \sa addAircraftToView */
    void addAircraftsToView(const QList<Aircraft>& aircrafts);
    //! Add single waypoint to waypoint view.
    /*! \param model
        \param waypoint
        \sa addWaypointsToView */
    void addWaypointToView(QStandardItemModel *model, const Waypoint &waypoint);
    //! Add waypoints to waypoint view.
    /*! \param model
        \param waypoint
        \sa addWaypointToView */
    void addWaypointsToView(QStandardItemModel *model, const QList<Waypoint> &waypoints);
    //! Save a JSON to a file.
    /*! \param filename
        \param content */
    void saveJsonDataAsFile(const QString &filename);
    //! Save a Aircraft waypoints to a file.
    /*! \param filename
        \param resolutionMs -1 or a resolution time (e.g. 5000ms) */
    void saveWaypointsAsKml(const QString &filename, qint64 resolutionMs = -1);
    //! Save a QString to a file.
    /*! \param filename
        \param content */
    void saveQStringToFile(const QString &filename, const QString &content);
    //! Write a message to the logger or qDebug
    /*! \param msg
        \param type
        \sa _logger */
    void loggerMessage(const QString &msg, QtMsgType msgType) const;
private slots:
    //! Triggering some delayed initializations.
    void slotDelayedInit();
    //! Menu connect FSX
    void onConnectFSXClicked();
    //! Menu disconnect FSX
    void onDisconnectFSXClicked();
    //! Start Web server
    void onStartWebServiceClicked();
    //! Stop Web server
    void onStopWebServiceClicked();
    //! Menu test FSX connection
    void onMenuFSXTest();
    //! Menu configure FSX settings
    void onMenuFSXConfigure();
    //! Menu save the JSON data
    void onMenuFSXSaveJsonData();
    //! Menu save KML data
    void onMenuFSXSaveKmlData(bool withReducedResolution = false);
    //! Menu save KML with reduced resolution
    void onMenuFSXSaveKmlDataReduced();
    //! Menu create local SimConnect.cfg
    void onMenuFSXCreateSimConnectCfg();
    //! Menu deltet local SimConnect.cfg
    void onMenuFSXDeleteSimConnectCfg();
    //! Menu configure KML settings
    void onMenuAppKmlConfigure();
    //! Menu configure Web server
    void onMenuWsConfigure();
    //! Menu show in browser
    void onMenuWsShowInBrowser();
    //! Menu show help
    void onMenuHelpShowOnlineHelp();
    //! About this applicaion
    void onMenuHelpAbout();
    //! Selection in aircraft list has been chaned
    /*! \param selected
        \param deselected */
    void onAircraftListSelectionChanged (const QItemSelection &selected, const QItemSelection &deselected);
    //! Set the waypoints tab (selected)
    void slotSetWaypointsTab();
    //! Set the console tab (selected)
    void slotSetConsoleTab();
public slots:
    //! Log a message (on the app's console / logger)
    /*! \param logMessage
        \param msgType severity */
    void slotLogMessage(const QString &logMessage, QtMsgType msgType);
    //! FSX message loop has been stopped
    void slotFSXMessageLoopStopped();
    //! FSX closed or shut down
    void slotFSXQuit();
    //! Called by timer, update aircrafts
    void slotUpdateAircrafts();
signals:
    //! Update the aircrafts list
    /*! \return list of aircrafts */
    QList<Aircraft> signalFSXAircrafts();
    //! Data on selected aircraft
    /*! \return Aircraft */
    Aircraft signalFSXFindById(const SIMCONNECT_OBJECT_ID id);
    //! Save JSON data (of aircrafts / waypoints)
    /*! \param parameter JSON parameters
        \return JSON string */
    QString  signalFSXAircraftsJsonData(const JsonParameter &parameter);
    //! HTML data (of aircrafts / waypoints)
    /*! \return HTML string */
    QString  signalFSXAircraftsHtmlTable();

};
} // namespace
#endif // FSXWSMAINWINDOW_H
